﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Threading;
using snat.model;

namespace gui {

    /// <summary>
    /// GUI Notifiable NodeStatsInfo Class for the Node Properties Tab
    /// Contains basenode, name, id, clusterid, messagesreceived, messagessent
    /// messagestotal, nodeindegree, nodeoutdegree, nodetotaldegree
    /// </summary>
    public class NodeStatsInfo : DependencyObject {

        public static NodeStatsInfo Instance;
        public static Dispatcher _Dispatcher { get; set; }

        public static DependencyProperty NodeProperty = DependencyProperty.Register("Node", typeof(BaseNode), typeof(NodeStatsInfo));
        public static DependencyProperty NodeNameProperty = DependencyProperty.Register("NodeName", typeof(string), typeof(NodeStatsInfo));
        public static DependencyProperty NodeIdProperty = DependencyProperty.Register("NodeId", typeof(int), typeof(NodeStatsInfo));
        public static DependencyProperty NodeStringProperty = DependencyProperty.Register("NodeString", typeof(string), typeof(NodeStatsInfo));
        public static DependencyProperty NodeClusterIdProperty = DependencyProperty.Register("NodeClusterId", typeof(int), typeof(NodeStatsInfo));  
        public static DependencyProperty MessagesReceivedProperty = DependencyProperty.Register("MessagesReceived", typeof(int), typeof(NodeStatsInfo));
        public static DependencyProperty MessagesSentProperty = DependencyProperty.Register("MessagesSent", typeof(int), typeof(NodeStatsInfo));
        public static DependencyProperty MessagesTotalProperty = DependencyProperty.Register("MessagesTotal", typeof(int), typeof(NodeStatsInfo));
        public static DependencyProperty NodeInDegreeProperty = DependencyProperty.Register("NodeInDegree", typeof(int), typeof(NodeStatsInfo));
        public static DependencyProperty NodeOutDegreeProperty = DependencyProperty.Register("NodeOutDegree", typeof(int), typeof(NodeStatsInfo));
        public static DependencyProperty NodeTotalDegreeProperty = DependencyProperty.Register("NodeTotalDegree", typeof(int), typeof(NodeStatsInfo));

        static NodeStatsInfo() {
            Instance = new NodeStatsInfo();
        }

        public ClusterNode Node {
            get { return (ClusterNode)GetValue(NodeProperty); }
            set { SetValue(NodeProperty, value); }
        }
        public string NodeName {
            get { return (string)GetValue(NodeNameProperty); }
            set { SetValue(NodeNameProperty, value); }
        }
        public int NodeId {
            get { return (int)GetValue(NodeIdProperty); }
            set { SetValue(NodeIdProperty, value); }
        }
        public string NodeString {
            get { return (string)GetValue(NodeStringProperty); }
            set { SetValue(NodeStringProperty, value); }
        }
        public int NodeClusterId {
            get { return (int)GetValue(NodeClusterIdProperty); }
            set { SetValue(NodeClusterIdProperty, value); }
        }
        public int MessagesReceived {
            get { return (int)GetValue(MessagesReceivedProperty); }
            set { SetValue(MessagesReceivedProperty, value); }
        }
        public int MessagesSent {
            get { return (int)GetValue(MessagesSentProperty); }
            set { SetValue(MessagesSentProperty, value); }
        }
        public int MessagesTotal {
            get { return (int)GetValue(MessagesTotalProperty); }
            set { SetValue(MessagesTotalProperty, value); }
        }
        public int NodeInDegree {
            get { return (int)GetValue(NodeInDegreeProperty); }
            set { SetValue(NodeInDegreeProperty, value); }
        }
        public int NodeOutDegree {
            get { return (int)GetValue(NodeOutDegreeProperty); }
            set { SetValue(NodeOutDegreeProperty, value); }
        }
        public int NodeTotalDegree {
            get { return (int)GetValue(NodeTotalDegreeProperty); }
            set { SetValue(NodeTotalDegreeProperty, value); }
        }

        public static void PopulateWithNode(ClusterNode node) {
            if (node.ID.Equals(null))
                DisplayNull();

            if (_Dispatcher != null) {
                _Dispatcher.BeginInvoke(
                    DispatcherPriority.Send,
                    new Action(delegate() {
                    Instance.Node = node;
                    Instance.NodeName = node.Name;
                    Instance.NodeId = node.ID;
                    Instance.NodeString = String.Join(": ", node.ID, node.Name);
                    Instance.NodeClusterId = node.ClusterID;
                    Instance.MessagesReceived = node.MessageReceivedCount;
                    Instance.MessagesSent = node.MessageSentCount;
                    Instance.MessagesTotal = node.MessageReceivedCount + node.MessageSentCount;
                    Instance.NodeInDegree = node.InDegree;
                    Instance.NodeOutDegree = node.OutDegree;
                    Instance.NodeTotalDegree = node.Degree;
                }));
            }
        }

        public static void UpdateDisplay() {
            if (Instance.Node == null) {
                DisplayNull();
                return;
            }

            if (_Dispatcher != null) {
                _Dispatcher.BeginInvoke(
                    DispatcherPriority.Send,
                    new Action(delegate() {
                    Instance.Node = Instance.Node;
                    Instance.NodeName = Instance.Node.Name;
                    Instance.NodeId = Instance.Node.ID;
                    Instance.NodeString = String.Join(": ", Instance.Node.ID, Instance.Node.Name);
                    Instance.NodeClusterId = Instance.Node.ClusterID;
                    Instance.MessagesReceived = Instance.Node.MessageReceivedCount;
                    Instance.MessagesSent = Instance.Node.MessageSentCount;
                    Instance.MessagesTotal = Instance.Node.MessageReceivedCount + Instance.Node.MessageSentCount;
                    Instance.NodeInDegree = Instance.Node.InDegree;
                    Instance.NodeOutDegree = Instance.Node.OutDegree;
                    Instance.NodeTotalDegree = Instance.Node.Degree;
                }));
            }
        }

        public static void DisplayNull() {
            if (_Dispatcher != null) {
                _Dispatcher.BeginInvoke(
                     DispatcherPriority.Send,
                    new Action(delegate() {
                        Instance.Node = null;
                        Instance.NodeName = "Select a node to view";
                        Instance.NodeId = 0;
                        Instance.NodeString = "Select a node to view";
                        Instance.NodeClusterId = 0;
                        Instance.MessagesReceived = 0;
                        Instance.MessagesSent = 0;
                        Instance.MessagesTotal = 0;
                        Instance.NodeInDegree = 0;
                        Instance.NodeOutDegree = 0;
                        Instance.NodeTotalDegree = 0;
                    }));
            }
        }

    }
}
